﻿
namespace BLPicker.Unity
{
    using System.Diagnostics.Contracts;
    using Microsoft.Practices.Unity;

    /// <summary>
    /// Factory for getting instance of business layer from a unity container.
    /// </summary>
    public class UnityBusinessLayerFactory<TBusinessLayer> : IBusinessLayerFactory<TBusinessLayer>
    {

        private readonly IUnityContainer _unityContainer;
        private readonly bool _throwIfNotFound;

        /// <summary>
        /// ctor.
        /// </summary>
        /// <param name="unityContainer">Instance of unity container</param>
        /// <param name="throwIfNotFound">Throw exception if dependency is not found.</param>
        public UnityBusinessLayerFactory(IUnityContainer unityContainer, bool throwIfNotFound = false)
        {
            Contract.Requires(unityContainer != null);

            _unityContainer = unityContainer;
            _throwIfNotFound = throwIfNotFound;
        }

        /// <summary>
        /// Gets unnamed instance of business layer from unity container.
        /// </summary>
        /// <returns>The unnamed instance of business layer.</returns>
        public TBusinessLayer GetBusinessLayer()
        {
            TBusinessLayer businessLayer;

            if (_throwIfNotFound)
            {
                businessLayer = _unityContainer.Resolve<TBusinessLayer>();
            }
            else
            {
                bool isRegistered = _unityContainer.IsRegistered<TBusinessLayer>();
                businessLayer = isRegistered
                    ? _unityContainer.Resolve<TBusinessLayer>()
                    : default(TBusinessLayer);
            }

            return businessLayer;
        }

        /// <summary>
        /// Gets named instance of business layer from unity container.
        /// </summary>
        /// <param name="name">Name of dependency in unity container.</param>
        /// <returns>The named instance of business layer.</returns>
        public TBusinessLayer GetBusinessLayer(string name)
        {
            TBusinessLayer businessLayer;

            if (_throwIfNotFound)
            {
                businessLayer = _unityContainer.Resolve<TBusinessLayer>(name);
            }
            else
            {
                bool isRegistered = _unityContainer.IsRegistered<TBusinessLayer>(name);
                businessLayer = isRegistered 
                    ? _unityContainer.Resolve<TBusinessLayer>(name)
                    : default(TBusinessLayer);
            }

            return businessLayer;
        }
    }
}
